<template>
  <div>
    <el-select
      v-model="optionsValue"
      :style="optionsStyle"
      :clearable="clearable"
      :placeholder="tipsText"
      :disabled="disabled"
      filterable
      :filter-method="queryOptions"
      :multiple="multiple"
      @change="retuenValue"
    >
      <el-option v-for="item in options" :key="item[requestKeyValue.value]" :label="item[requestKeyValue.label]" :value="item[requestKeyValue.value]" />
    </el-select>
  </div>
</template>
<script>
/*
  1. request必传
  2. 获取所选项的值可以通过父子组件传递 @getValue="function"
  3. 重置内容可以通过$refs调用resetValue()
  4. 如果有多个参数,请 queryParam / fixedParams 配合使用
      fixedParams: {
        key: value,
        ...
      }
  5. 选择器默认label是name, 默认value是id, 自定义请通过 requestKeyValue 传参 (需要一个对象)
      requestKeyValue: { label: label, value: value}
  6. 查找对应值的格式(至少需要传递一个label一个value,只有一个值时只需传递一个对象)
      findValue: [
        { label: label, value: value }
        ...
      ]
 */
import utils from '../../utils/utils.js'
import request from '@/utils/request'
export default {
  props: {
    request: { // 请求
      type: String,
      default: '',
      required: true
    },
    tipsText: { // 提示文字
      type: String,
      default: '请选择'
    },
    queryParam: { // value需要修改的查询参数
      type: String,
      default: 'name'
    },
    fixedParams: { // value不需要修改的查询参数
      type: Object,
      default: () => {}
    },
    requestKeyValue: { // 选择器显示的值跟提交的值
      type: Object,
      default: () => {
        return {
          'label': 'name',
          'value': 'id'
        }
      }
    },
    findValue: { // 查询对应的值
      type: Array,
      default: () => []
    },
    multiple: { // 是否多选
      type: Boolean,
      default: false
    },
    optionsStyle: { // 控制样式
      type: String,
      default: 'width: auto'
    },
    otherData: { // 外界传递进来的其他数据
      type: null
    },
    clearable: { // 是否可清空
      type: Boolean,
      default: true
    },
    disabled: { // 是否禁用
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      options: [],
      mark: false, // 防抖
      optionsValue: ''
    }
  },
  created() {
    this.queryOptions()
  },
  methods: {
    queryOptions(query) {
      clearTimeout(this.mark)
      this.mark = setTimeout(() => {
        this.options = []
        const params = { [this.queryParam]: query }
        if (!utils.isNull(this.fixedParams)) { // 如果有固定参数,则添加到params里
          for (const key in this.fixedParams) {
            params[key] = this.fixedParams[key]
          }
        }
        request({
          url: '/admin/' + this.request + '/list',
          method: 'get',
          params: params
        }).then(res => {
          this.options = res.data.data
          if (!utils.isNull(this.findValue)) { // 如果有传入的值
            if (this.multiple) { // 多选
              this.optionsValue = [] // 多选对应的值会转成一个数组,所以要用把原来的字符串类型转成数组类型
              for (let i = 0; i < this.findValue.length; i++) {
                if (utils.isNull(this.findValue[i][this.requestKeyValue.value])) { continue }
                this.optionsValue.push(this.findValue[i][this.requestKeyValue.value])
                const notFound = this.options.find(val => { return val[this.requestKeyValue.value] == this.findValue[i][this.requestKeyValue.value] }) // 找到列表里没有的数据
                if (!notFound) {
                  const obj = {
                    [this.requestKeyValue.label]: this.findValue[i][this.requestKeyValue.label],
                    [this.requestKeyValue.value]: this.findValue[i][this.requestKeyValue.value]
                  }
                  this.options.unshift(obj) // 把没有的数据添加到下拉列表里
                }
              }
              /* this.findValue.forEach((item, index) => {
                this.optionsValue.push(item[this.requestKeyValue.value])
                const notFound = this.options.find(val => { return val[this.requestKeyValue.value] == item[this.requestKeyValue.value] }) // 找到列表里没有的数据
                if (!notFound) {
                  const obj = {
                    [this.requestKeyValue.label]: this.findValue[index][this.requestKeyValue.label],
                    [this.requestKeyValue.value]: item[this.requestKeyValue.value]
                  }
                  this.options.unshift(obj) // 把没有的数据添加到下拉列表里
                }
              }) */
            } else { // 单选
              if (utils.isNull(this.findValue[0][this.requestKeyValue.value])) { return }
              const notFound = this.options.find(val => { return val[this.requestKeyValue.value] == this.findValue[0][this.requestKeyValue.value] }) // 找到列表里没有的数据
              this.optionsValue = this.findValue[0][this.requestKeyValue.value]
              if (!notFound) {
                const obj = {
                  [this.requestKeyValue.label]: this.findValue[0][this.requestKeyValue.label],
                  [this.requestKeyValue.value]: this.findValue[0][this.requestKeyValue.value]
                }
                this.options.unshift(obj) // 把没有的数据添加到下拉列表里
              }
            }
            this.retuenValue() // 返回数据给外界
          }
        }).catch(() => {})
      }, 300)
    },
    resetValue() {
      this.optionsValue = ''
      const data = this.options.find(val => { return val[this.requestKeyValue.value] == this.optionsValue })
      this.$emit('getValue', this.optionsValue) // 返回当前选中选项的value
      this.$emit('getAllData', data) // 返回当前选中选项的所有数据
      this.$emit('getAllDataOtherData', data, this.otherData) // 返回当前选中选项的所有数据 + 外界传递过来的数据
    },
    retuenValue() {
      const data = this.options.find(val => { return val[this.requestKeyValue.value] == this.optionsValue })
      this.$emit('getValue', this.optionsValue) // 返回当前选中选项的value
      this.$emit('getAllData', data) // 返回当前选中选项的所有数据
      this.$emit('getAllDataOtherData', data, this.otherData) // 返回当前选中选项的所有数据 + 外界传递过来的数据
    }
  }
}
</script>

<style scoped lang="scss"></style>
